/*--------------------------------------------------------------
 * File: uart.c 编码类型：C语言  UTF-8
 * Author WRS (1352509846@qq.com)
 * 功能: 串口读写
 * Version 0.1
 * Date 2024-09-27 
 * 
 * @copyright Copyright (c) 2024
 * 
----------------------------------------------------------------*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_log.h"
#include "my_uart.h"
#include <string.h>
#include "system/inc/global.h"

static const char *TAG = "UART";

#define ECHO_TEST_TXD (17)
#define ECHO_TEST_RXD (16)
#define ECHO_TEST_RTS (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS (UART_PIN_NO_CHANGE)

#define ECHO_UART_BAUD_RATE     (115200)
// #define ECHO_TASK_STACK_SIZE    (2048)

#define RX_BUF_SIZE (2048)
#define TX_BUF_SIZE (2048)

#define UART_QUEUE_SIZE     10

static QueueHandle_t uart_queue;    // 存储待发送数据的队列
SemaphoreHandle_t uart_mutex;       // 全局互斥锁

void uart_send_task(void *pvParameter);

void uart_Init(void)
{
    uart_config_t uart_config = 
    {
        .baud_rate = ECHO_UART_BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    int intr_alloc_flags = 0;

#if CONFIG_UART_ISR_IN_IRAM
    intr_alloc_flags = ESP_INTR_FLAG_IRAM;
#endif

    ESP_ERROR_CHECK(uart_driver_install(UART_NUM_2, RX_BUF_SIZE, TX_BUF_SIZE, 0, NULL, intr_alloc_flags));
    ESP_ERROR_CHECK(uart_param_config(UART_NUM_2, &uart_config));
    ESP_ERROR_CHECK(uart_set_pin(UART_NUM_2, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS));

    // 创建发送数据的队列
    uart_queue = xQueueCreate(UART_QUEUE_SIZE, sizeof(uart_item_t));
    // 创建全局互斥锁
    uart_mutex = xSemaphoreCreateMutex();
    // 创建发送任务
    xTaskCreate(uart_send_task, "uart_send_task", 2048, NULL, 5, NULL);

    ESP_LOGI(TAG, "uart_Init");
}

void uart_DeInit(void)
{
    // 等待 UART 完成发送操作 最多等待300ms
    ESP_ERROR_CHECK(uart_wait_tx_done(UART_NUM_2, 300));
    // 停止 UART 驱动
    ESP_ERROR_CHECK(uart_driver_delete(UART_NUM_2));
}

void USART_Send(uint32_t COMx , uint8_t *buf , uint16_t length)
{
    uart_item_t item;
    uint8_t *tx_data = NULL;

    if(buf == NULL || length == 0)
    {
        ESP_LOGI(TAG, "USART_Send buf is null or length is 0");
        return;
    }

    tx_data = pvPortMalloc(length);
    if(tx_data == NULL)
    {
        ESP_LOGI(TAG, "USART_Send malloc error");
        return;
    }

    // 加锁保护共享资源（队列和 UART 操作）
    if (xSemaphoreTake(uart_mutex, portMAX_DELAY) == pdTRUE) 
    {
        item.COMx = COMx;        
        memcpy(tx_data, buf, length);
        item.buf = tx_data;
        item.len = length;

        xQueueSend(uart_queue, &item, portMAX_DELAY);
        xSemaphoreGive(uart_mutex);
    } 
    else 
    {
        vPortFree(tx_data);  // 获取锁失败，释放内存
    }
}

void uart_send_task(void *pvParameter)
{
    uint16_t len = 0;;
    uart_item_t item;
    
    while (1)
    {
        uart_get_buffered_data_len(Env_st.MasterPort, &len);
        if(len > 0)
        {
            vTaskDelay(5);
        }
        else
        {
            vTaskDelay(2);
            uart_get_buffered_data_len(Env_st.MasterPort, &len);
            if(len == 0)
            {
                if (xQueueReceive(uart_queue, &item, portMAX_DELAY) == pdTRUE)
                {
                    // 发送数据
                    uart_write_bytes(item.COMx, item.buf, item.len);
                    uart_wait_tx_done(item.COMx, portMAX_DELAY); // 等待完成
                    // 释放内存（如果数据是动态分配的）
                    if(item.buf != NULL)
                    {
                        vPortFree(item.buf);
                        item.buf = NULL;
                    }
                }
            }            
        }        
    }
}
